package com.cloud.order.web;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.annotation.PostConstruct;

import com.cloud.service.api.IOrderApi;
import com.cloud.service.response.ResultResponse;
import com.cloud.service.util.BeanAndMapTransform;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import io.micrometer.core.instrument.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.*;

import com.cloud.order.dao.OrderRepository;
import com.cloud.order.domain.Order;
import com.cloud.service.dto.OrderDTO;

/**
 * 提供Feign服务给user服务
 *
 * @author qinxh
 * @date 2019/07/26
 */
@RestController
@SuppressWarnings("unchecked")
public class OrderResourceController implements IOrderApi {

    @Autowired
    private OrderRepository orderRepository;

	/**
	 *  TIPS：PostConstruct注解在服务器加载Servlet时候运行，并且只会被服务器执行一次
	 */
	@PostConstruct
    public void init() {

        Order order = new Order();
        order.setAmount(100);
        order.setTitle("MyOrder");
        order.setDetail("Bought a imooc course");
        /*使用H2作为内嵌的内存数据库。写入数据库完成测试，内存数据库不提供数据的持久化存储；当应用启动时需要填充数据库，当应用结束时数据将会丢弃*/
        orderRepository.save(order);
    }

    @GetMapping("/list")
    public List<Order> getList(){

       return orderRepository.findAll();
    }

    /**
     * 如果实现的接口包含注解 @RequestBody，那么实现方法也需要带上注解 @RequestBody，否则Feign调用会报错，而如果作为单独项目调用接口参数值将为空
     *
     * @param orderDTO
     * @return
     */
    @Override
    @PostMapping("/order")
    public ResultResponse<Long> post(@RequestBody OrderDTO orderDTO) {

        Order order = new Order();
        BeanUtils.copyProperties(orderDTO,order);

        return ResultResponse.ofSuccess(orderRepository.save(order).getId());
    }

    @Override
    public ResultResponse<Integer> delete(@PathVariable("id") Long id) {

        Order order = new Order();
        order.setId(id);
        orderRepository.delete(order);
        return ResultResponse.ofSuccess(1);
    }

    @Override
    public ResultResponse<Integer> put(@RequestBody OrderDTO orderDTO) {

	    if(orderDTO == null || orderDTO.getId() == null){
	        return ResultResponse.ofMessage("100000","请求参数错误");
        }

        Optional<Order> byId = orderRepository.findById(orderDTO.getId());
        if(!byId.isPresent()){
            return ResultResponse.ofMessage("100000","数据不存在");
        }
        Order one = byId.get();
        one.setTitle(orderDTO.getTitle());
        one.setDetail(orderDTO.getDetail());
        one.setAmount(orderDTO.getAmount());

        orderRepository.save(one);

        return ResultResponse.ofSuccess(1);
    }

    /**
     * HystrixCommand注解表示使此url受 Hystrix 监控
     */
    @HystrixCommand
    @Override
    public ResultResponse<List<OrderDTO>> get(@RequestParam Map<String,Object> map) {

        OrderDTO orderDTO = BeanAndMapTransform.map2Bean(map, OrderDTO.class);
        if(orderDTO == null || StringUtils.isBlank(orderDTO.getTitle())){
            return ResultResponse.ofSuccess(null);
        }

        return ResultResponse.ofSuccess(orderRepository.findOneByTitle(orderDTO.getTitle()));
    }

    /**
     * 如果实现的接口包含注解 @PathVariable，那么实现方法也需要带上注解 @PathVariable，否则Feign调用会报错，而如果作为单独项目调用接口参数值将为空
     *
     * @param id                            主键id
     * @return
     */
    @Override
    public ResultResponse<OrderDTO> details(@PathVariable("id") Long id) {

        Optional<Order> byId = orderRepository.findById(id);
        if(!byId.isPresent()){
            return ResultResponse.ofMessage("100000","数据不存在");
        }
        OrderDTO dto = new OrderDTO();
        BeanUtils.copyProperties(byId.get(),dto);

        return ResultResponse.ofSuccess(dto);
    }

    @Override
    public ResultResponse<List<OrderDTO>> get0(OrderDTO oder){

        if(oder == null || StringUtils.isBlank(oder.getTitle())){
            return ResultResponse.ofSuccess(null);
        }

        return ResultResponse.ofSuccess(orderRepository.findOneByTitle(oder.getTitle()));
    }
}
